
// === uuMeta.ajax.jsonp ===
// depend: uuMeta, uuMeta.url, uuMeta.date, uuMeta.ajax
/*
uuMeta.ajax.jsonp(url, callback = void 0,
                  param = { timeout, ngcallback, method })
 */
(function uuMetaAjaxJsonp() {
var _mm = uuMeta,
    _jobdb = {}, // job db
    _jobid  = 0; // job id

// uuMeta.ajax.jsonp - Async JSONP request
//    uuMeta.ajax.jsonp("http://example.com/a.php", function(json) {});
//
//        Hash: { timeout: 10000, method: "callback", ngcallback: void 0 }
//
//        Number: timeout, request timeout
//        String: method, "callback"
//        Function: ngcallback, ngcallback(state, url)
//
function jsonp(url,      // @param URLString: request url
               callback, // @param Function(= undefined): callback function
               param) {  // @param Hash(= undefined):
                         //          { timeout, method, ngcallback }
  url = _mm.url.abs(url);
  param = param || {};

  var timeout = param.timeout || 10000,
      method = param.method || "callback",
      jobid = "jsonp" + ++_jobid,
      node = document.createElement("script"),
      hash = _mm.url.parse(url),
      ng = param.ngcallback;

  // add QueryString( "&callback=uuMeta.ajax.jsonp.db.jsonp1" )
  hash.hash[method] = "uuMeta.ajax.jsonp.db." + jobid;
  hash.query = _mm.url.buildQuery(hash.hash);

  function DIE() {
    _mm.head.removeChild(node);
    delete _jobdb[jobid];
  }

  _jobdb[jobid] = function(json, code) {
    if (!node._run++) {
      json ? (callback && callback(json, url))
           : (ng && ng(code || 404));
      setTimeout(DIE, timeout + 100000);
    }
  };

  // <head>
  //   <script src="..." type="text/javascript" charset="utf-8"></script>
  // </head>
  node._run = 0;
  node.type = "text/javascript";
  node.charset = "utf-8";
  _mm.head.appendChild(node);
  node.setAttribute("src", _mm.url.build(hash));

  // watchdog
  setTimeout(function() {
    _jobdb[jobid]("", 408); // 408 "Request Time-out"
  }, timeout);
}

// --- initialize ---

// --- export ---
_mm.ajax.jsonp = jsonp; // uuMeta.ajax.jsonp
jsonp.db = _jobdb; // ref

})(); // uuMeta.ajax.jsonp scope

